/**
 * StoreView.java Class
 * 
 * This class represents the store for Oregon Trail. This class sets up the GUI 
 * elements and the necessary components for the users to buy items for their 
 * Journey.
 * 
 * @author Clay, Robert, Huy, Kellie, Matt
 * @version 1.0
 * 
 * GUI Notes for Team:
 * The GUI layout that I am using for this class is called a Java "Absolute Layout." 
 * This means that I can add element anywhere that I want to on JPanels. Just so we 
 * are all on the same page, I am able to manipulate the location of each GUI element 
 * by the following call: itemname.setBounds(x location, y location, width, height);
 * I have labeled all of the areas in this file where I have set the location, but 
 * if you have any questions, feel free to give me a call. 
 */

package edu.gatech.cs2340.bytebankers.view;

import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Point;

import javax.swing.JButton;

import com.sun.org.apache.bcel.internal.generic.NEW;

import edu.gatech.cs2340.bytebankers.presenter.IStorePresenter;

import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DecimalFormat;
import java.text.NumberFormat;

public class StoreView extends JPanel implements IStoreView {

    private JTextField textField_7;
    private IStorePresenter presenter;
    private double bankroll;
    private double[] price;
    private String[] itemName;
    private int[] inventQuant;
    private double[] weight;
    private String storeName;
    private double weightAvailable;
    private JTextField[] userInputFields;
    private double purchaseTotal;
    private int purchaseWeight;
    JPanel mPanel = new JPanel();
    JButton btnCheckout = new JButton();
    JLabel lblCurrentMoney = new JLabel();
    JLabel lblWeightAvailable = new JLabel();;
    NumberFormat nf = NumberFormat.getCurrencyInstance();
    NumberFormat df = new DecimalFormat("#.##");

    /**
     * Constructor brings in the store presenter.
     */
    public StoreView(IStorePresenter presenter) {
	this.presenter = presenter;

    }

    /**
     * setInventory Method for setting up the inventory for the player This
     * method also sets up the GUI layout for the store
     * 
     * @param double[] price array of prices for items
     * @param String
     *            [] itemName array of item names
     * @param int[] inventQuant array of item quantities
     * @param double[] weight array of item weights
     */
    public void setInventory(double[] price, String[] itemName,
	    int[] inventQuant, double[] weight) {
	setLayout(null);

	/**
	 * This labels the store
	 */
	JLabel lblGeneralStore = new JLabel(storeName);
	lblGeneralStore.setBounds(580, 30, 260, 30); // sets location of the
						     // store
						     // name JLabel
	lblGeneralStore.setHorizontalAlignment(SwingConstants.RIGHT);
	lblGeneralStore.setForeground(new Color(255, 255, 255));
	lblGeneralStore.setFont(new Font("Lucida Grande", Font.BOLD, 16));

	add(lblGeneralStore);

	/**
	 * Checkout button. This button will only appear when the user is making
	 * valid purchases. For example, this button will not appear if the user
	 * attempts to purchase too many of one item, when they do not have
	 * enough money.
	 */
	btnCheckout.setText("Checkout");
	btnCheckout.addMouseListener(new MouseAdapter() {
	    @Override
	    public void mouseClicked(MouseEvent arg0) {
		CheckoutClicked();
	    }
	});
	btnCheckout.setBounds(675, 180, 117, 29); // Sets the location of the
						  // button
	add(btnCheckout);

	/**
	 * JLabel instructions on how to use the store
	 */
	JLabel lblEnterTheAmount = new JLabel(
		"Enter the amount of items that you want to buy and click \"Checkout\" to continue.");
	lblEnterTheAmount.setBounds(50, 110, 513, 16); // sets the location of
						       // the
						       // instructions JLabel
	lblEnterTheAmount.setForeground(new Color(255, 255, 255));
	add(lblEnterTheAmount);

	/**
	 * The following 5 JLablel's are arranged on an absolute layout. These
	 * JLablel's are the titles for each section of the table.
	 */
	JLabel lblItem = new JLabel("Item");
	lblItem.setBounds(164, 150, 28, 16); // sets location of JLabel
	lblItem.setForeground(new Color(255, 255, 255));
	add(lblItem);

	JLabel lblQtyToBuy = new JLabel("<html>Quantity to Buy</html>");
	lblQtyToBuy.setBounds(90, 140, 65, 32); // sets location of JLabel
	lblQtyToBuy.setForeground(new Color(255, 255, 255));
	add(lblQtyToBuy);

	JLabel lblPrice = new JLabel("Price");
	lblPrice.setBounds(278, 150, 30, 16); // sets location of JLabel
	lblPrice.setForeground(new Color(255, 255, 255));
	add(lblPrice);

	JLabel lblWeight = new JLabel("Weight");
	lblWeight.setBounds(390, 150, 43, 16); // sets location of JLabel
	lblWeight.setForeground(new Color(255, 255, 255));
	add(lblWeight);

	JLabel lblQtyInInventory = new JLabel(
		"<html>Quantity in <p>Inventory</html>");
	lblQtyInInventory.setBounds(505, 142, 101, 32); // sets location of
							// JLabel
	lblQtyInInventory.setForeground(new Color(255, 255, 255));
	add(lblQtyInInventory);

	// mPanel.setLocation(new Point(25, 100));
	mPanel.setPreferredSize(new Dimension(800, 150));
	mPanel.setLayout(new GridLayout(18, 1));
	mPanel.setOpaque(false);
	add(mPanel);

	this.price = price;
	this.inventQuant = inventQuant;
	this.itemName = itemName;
	this.weight = weight;
	userInputFields = new JTextField[price.length];

	/**
	 * This for loop sets up the items in a grid layout.
	 */
	for (int i = 0; i < this.itemName.length; i++) {
	    JPanel panel1 = new JPanel();
	    JPanel txtPanel = new JPanel();
	    panel1.setOpaque(false);
	    txtPanel.setOpaque(false);
	    JTextField qty = new JTextField(2);
	    LostFocusListener listener = new LostFocusListener();
	    qty.addFocusListener(listener);
	    txtPanel.add(qty);
	    userInputFields[i] = qty;
	    JLabel Name = new JLabel(itemName[i]);
	    Name.setForeground(new Color(255, 255, 255));
	    JLabel Price = new JLabel(nf.format(((Double) price[i])).toString());
	    Price.setForeground(new Color(255, 255, 255));
	    JLabel Weight = new JLabel(((Double) weight[i]).toString());
	    Weight.setForeground(new Color(255, 255, 255));
	    JLabel Inventory = new JLabel(((Integer) inventQuant[i]).toString());
	    Inventory.setForeground(new Color(255, 255, 255));
	    panel1.setLayout(new GridLayout(1, 7));
	    panel1.add(txtPanel);
	    panel1.add(Name);
	    panel1.add(Price);
	    panel1.add(Weight);
	    panel1.add(Inventory);
	    for (int j = 0; j < 2; j++) {
		panel1.add(new JLabel());
	    }
	    mPanel.add(panel1);
	    mPanel.setBounds(50, 175, 800, 800); // sets location of each added
						 // GridLayout in the array. Do
						 // not change these values
	}

	/**
	 * This JPanel named "moneypanel" is the green panel in the upper right
	 * hand corner of the GUI. This panel's purpose is only for displaying a
	 * background color for the "Current Bankroll" panel and creating a
	 * place to insert the "Current Bankroll" JLabel.
	 */
	JPanel moneypanel = new JPanel();
	moneypanel.setBackground(new Color(0, 0, 0)); // sets the background
						      // color of the
						      // "moneypanel"
						      // JPanel. This color
						      // should be dark green
						      // until until the user
						      // attempts to but too
						      // much, then it will
						      // turn red.
	// panel.setPreferredSize(new Dimension(800, 500));
	moneypanel.setBounds(630, 100, 210, 26); // sets location of
						 // "moneypanel"
						 // JPanel
	add(moneypanel);

	/**
	 * This JPanel named "weightpanel" is the green panel in the upper right
	 * hand corner of the GUI, directly below the "moneypanel". This panel's
	 * purpose is only for displaying a background color for the
	 * "Current Weight" panel and creating a place to insert the
	 * "Current Weight" JLabel.
	 */
	JPanel weightpanel = new JPanel();
	weightpanel.setBackground(new Color(0, 0, 0)); // sets the background
						       // color of the
						       // "weightpanel"
						       // JPanel. This color
						       // should be dark
						       // green until until
						       // the user attempts
						       // to but too much,
						       // then it will turn
						       // red.
	// panel.setPreferredSize(new Dimension(800, 500));
	weightpanel.setBounds(630, 130, 210, 26); // sets location of
						  // "weightpanel" JPanel
	add(weightpanel);

	moneypanel.setLayout(null); // sets no active layout for the
				    // "moneypanel" JPanel

	/**
	 * This text is added to the "moneypanel" added above. This text will
	 * update after the user has purchases items to the correct money left.
	 */
	lblCurrentMoney.setText("Available Bankroll: " + nf.format(bankroll));
	lblCurrentMoney.setBounds(6, 6, 220, 16); // sets the location of the
						  // "Available Bankroll" text
						  // inside the "moneypanel"
						  // JPanel
	lblCurrentMoney.setForeground(new Color(248, 248, 255)); // sets the
								 // color of the
								 // text inside
								 // the
								 // "moneypanel"
								 // JPanel
	moneypanel.add(lblCurrentMoney);

	/**
	 * This text is added to the "weightpanel" above. This text will be
	 * updated after the user purchases items from the store and reflects
	 * the correct weight.
	 */
	lblWeightAvailable.setText("Available Weight: "
		+ df.format(weightAvailable));
	lblWeightAvailable.setBounds(6, 26, 300, 16); // sets the location of
						      // the "Available Weight"
						      // text inside the
						      // "weightpanel" JPanel
	lblWeightAvailable.setForeground(new Color(248, 248, 255)); // sets the
								    // color of
								    // the text
								    // inside
								    // the
								    // "weightpanel"
								    // JPanel
	weightpanel.add(lblWeightAvailable);

	this.invalidate();
	this.repaint();

	mPanel.invalidate();
	mPanel.repaint();

	// add the background image
	JLabel label = new JLabel("");

	label.setIcon(new ImageIcon(
		StoreBGView.class
			.getResource("/edu/gatech/cs2340/bytebankers/graphics/StoreBG.jpg")));

	label.setBounds(0, 0, 860, 500);
	add(label);

    }

    /**
     * Setter for the current bankroll of the player
     */
    public void setBankroll(double bankroll) {
	this.bankroll = bankroll;
    }

    /**
     * Getter for available weight
     * 
     * @return double available weight
     */
    public double getWeightAvailable() {
	return weightAvailable;
    }

    /**
     * Setter for available weight
     */
    public void setWeightAvailable(double weightAvailable) {
	this.weightAvailable = weightAvailable;
    }

    /**
     * Setter for the store name
     */
    public void setName(String storeName) {
	this.storeName = storeName;
    }

    /**
     * Getter for item names in store
     * 
     * @return String name of item
     */
    public String[] getItemName() {
	return itemName;
    }

    /**
     * Setter for item names in store
     */
    public void setItemName(String[] itemName) {
	this.itemName = itemName;
    }

    /**
     * CheckoutClicked Method to handle the "Checkout" button
     */
    public void CheckoutClicked() {
    	getInventQuant();
    	presenter.checkoutClicked();
    }

    /**
     * Getter for number of items in player's inventory
     * 
     * @return int quantity of item's in inventory
     */
    public int[] getInventQuant() {
		for (int i = 0; i < itemName.length; i++) {
			try {
				
				inventQuant[i] = Integer.parseInt(userInputFields[i].getText().trim()); 
			} catch (Exception e) {
				inventQuant[i] = 0;
			}
		}
		return inventQuant;
	}

    /**
     * Setter for number of items in inventory
     */
    public void setInventQuant(int[] inventQuant) {
	this.inventQuant = inventQuant;
    }

    /**
     * Text field for user input. This input field is the quantities that the
     * user enters at the store.
     */
    public JTextField[] getUserInputFields() {
	return userInputFields;
    }

    /**
     * Setter for use input fields in the above JText field
     */
    public void setUserInputFields(JTextField[] userInputFields) {
	this.userInputFields = userInputFields;
    }

    /**
     * Getter for available money
     * 
     * @return double available money
     */
    public double getBankroll() {
	return bankroll;
    }

    /**
     * This method computes the total purchase price for items the user is
     * tryint to buy.
     * 
     * @return purchase price
     */
  
    public double computeTotal() {
	int total = 0;
	for (int i = 0; i < userInputFields.length; i++) {
	    try {
		if (userInputFields[i] != null) {
		    total += Integer.parseInt(userInputFields[i].getText()
			    .trim()) * price[i];
		} else {
		    total += 0;

		}
	    } catch (Exception e) {
		// user's input is invalid
		// pop up an error msg
	    }
	}
	return total;
    }

    /**
     * This method computes the total weight of all items purchased.
     * 
     * @return weight of purchase
     */
    public int computeWeightOfPurchase() {
	int weightOfPurchase = 0;
	for (int i = 0; i < userInputFields.length; i++) {
	    try {
		if (userInputFields[i] != null) {
		    if (itemName[i] != "Ox") {
			weightOfPurchase += Integer.parseInt(userInputFields[i]
				.getText().trim()) * weight[i];
		    }
		} else {
		    weightOfPurchase += 0;
		}
	    } catch (Exception e) {
		// user's input is invalid
		// pop up an error msg
	    }
	}
	return weightOfPurchase;

    }

    /**
     * Getter for the quantity of item array
     * 
     * @return int quantity of items in inventory
     */
    public int[] getQuant() {
	return inventQuant;
    }

    /**
     * Setter for the available weight of the wagon.
     */
    public void setAvailableWeight(double weightAvailable) {
	this.weightAvailable = weightAvailable;
    }

    /**
     * Private inner class for Listener
     */
    private class LostFocusListener implements FocusListener {

	/**
	 * Do nothing
	 */
	public void focusGained(FocusEvent e) {
	    // TODO Auto-generated method stub

	}

	/**
	 * Listener for the store quantity changes
	 */
	public void focusLost(FocusEvent e) {
	    double purchase = 0;
	    int weightOfPurchase = 0;
	    for (int i = 0; i < getItemName().length; i++) {
		if (e.getComponent() == getUserInputFields()[i]) {
		    try {
			if (!getUserInputFields()[i].getText().trim().isEmpty()) {
			    Integer.parseInt(getUserInputFields()[i].getText()
				    .trim());
			}
			purchase += computeTotal();
			weightOfPurchase += computeWeightOfPurchase();
			if (purchase > getBankroll()
				&& weightOfPurchase > getWeightAvailable()) {
			    btnCheckout.setEnabled(false);
			    lblCurrentMoney.setBackground(Color.red);
			    lblWeightAvailable.setBackground(Color.red);
			    ((JTextField) e.getComponent()).selectAll();
			} else if (purchase < getBankroll()
				&& weightOfPurchase < getWeightAvailable()) {
			    btnCheckout.setEnabled(true);
			    lblCurrentMoney.setBackground(Color.black);
			    lblWeightAvailable.setBackground(Color.black);
			}
			if (purchase > getBankroll()
				&& weightOfPurchase < getWeightAvailable()) {
			    btnCheckout.setEnabled(false);
			    lblCurrentMoney.setBackground(Color.red);
			    lblWeightAvailable.setBackground(Color.black);
			    ((JTextField) e.getComponent()).selectAll();
			} else if (purchase < getBankroll()
				&& weightOfPurchase > getWeightAvailable()) {
			    btnCheckout.setEnabled(false);
			    lblCurrentMoney.setBackground(Color.black);
			    lblWeightAvailable.setBackground(Color.red);
			    ((JTextField) e.getComponent()).selectAll();
			}
			lblCurrentMoney.setText("Available Bankroll: "
				+ nf.format(getBankroll() - purchase));
			lblWeightAvailable
				.setText("Available Weight: "
					+ df.format((getWeightAvailable() - weightOfPurchase)));
			lblCurrentMoney.setOpaque(true);
			lblWeightAvailable.setOpaque(true);
		    } catch (Exception e2) {
			JOptionPane
				.showMessageDialog(null,
					"Invalid quantity.  Please enter a valid quantity.");
			((JTextField) e.getComponent()).setText("");
			((JTextField) e.getComponent()).requestFocus();
		    }
		}
	    }
	}

    }

    /**
     * returns the store panel
     * 
     * @return store panel
     */
    public JPanel getMainPanel() {
	return this;
    }
}
